#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "LinkedList.h"

/**
 * 链表初始化
 *
 * 创建一个新的链表头节点，为其分配内存空间，初始化成员变量，并返回指向该节点的指针
 */
ListPointer LinkedListInit(void *data)
{
    // 存储新创建的头节点地址
    ListPointer headPointer;
    // 动态分配内存，大小为 struct LinkedList 结构体的字节数（即一个链表节点的大小）
    // 强制类型转换：(ListPointer) 将 malloc 返回的 void* 指针转换为 struct LinkedList* 类型（符合 ListPointer 定义）
    // malloc 分配的内存未初始化，可能包含随机垃圾数据，需后续处理
    headPointer = (ListPointer)malloc(sizeof(struct LinkedList));
    // 检查 malloc 是否成功分配内存
    if (headPointer == NULL)
    {
        printf("LinkedListInit(): Memory error.\n");
        return NULL;
    }
    // 使用 memset 将新节点的所有字节初始化为 0（二进制 0）
    // listData 初始为 0
    // listNext 被初始化为 NULL（因为 0 在指针语境中等价于 NULL），避免因未初始化导致的“野指针”问题（即指针指向随机内存地址）。
    memset(headPointer, 0, sizeof(struct LinkedList));
    // 将参数 data（用户传入的头节点数据）赋值给新节点的 listData 成员（数据域），完成头节点数据的存储。
    headPointer->listData = data;
    // 返回初始化完成的头节点指针，供后续链表操作（如添加节点、打印等）使用
    return headPointer;
}

/**
 * 链表数据打印
 *
 * 功能：遍历链表并打印所有节点的数据。
 * 参数：
 * ListPointer headPointer：链表的头节点指针（遍历起点）。
 * void (*pointerStr)(ListPointer)：函数指针，指向一个用于打印单个节点数据的函数
 * （因listData是void*类型，需根据实际数据类型自定义打印逻辑，例如打印int或字符串的方式不同）。
 */
void LinkedListPrint(ListPointer headPointer, void (*pointerStr)(ListPointer))
{
    ListPointer listPointer;
    listPointer = headPointer->listNext;
    while (listPointer != NULL)
    {
        pointerStr(listPointer);
        listPointer = listPointer->listNext;
    }

    // FIXME 待完善：链表数据打印
}

/**
 * 添加链表节点
 *
 * 功能：向链表中添加新节点（通常添加到尾部，具体逻辑取决于实现）。
 * 参数：
 * ListPointer headPointer：链表的头节点指针。
 * void *data：新节点要存储的数据。
 * 返回值：int类型，通常表示操作结果（例如0表示成功，非0表示失败，如内存分配失败）。
 */
int LinkedListAdd(ListPointer headPointer, void *data)
{
    ListPointer newPointer, listPointer;
    listPointer = headPointer;
    newPointer = LinkedListInit(data);
    // 链表偏移到尾节点
    while (listPointer->listNext != NULL)
    {
        listPointer = listPointer->listNext;
    }
    // 往尾节点添加数据
    listPointer->listNext = newPointer;
}

/**
 * 链表节点计数
 *
 * 功能：统计链表中节点的数量
 * 参数：
 * ListPointer headPointer：是通过 typedef 定义的别名，等价于 struct LinkedList *（指向链表节点的指针）。这是链表的头节点指针，作为遍历计数的起点。
 * 返回值：int 类型，返回链表中节点的总数量（包含头节点）。
 */
int LinkedListCount(ListPointer headPointer)
{
    ListPointer listPointer;
    int countResult = 0;
    listPointer = headPointer->listNext;
    while (listPointer != NULL)
    {
        countResult++;
        listPointer = listPointer->listNext;
    }
    return countResult;
}

/**
 * 链表释放
 *
 * 功能：释放整个链表占用的内存（遍历所有节点，依次释放每个节点的空间，避免内存泄漏）。
 * 参数：ListPointer headPointer：链表的头节点指针（释放起点）。
 */
void LinkedListFree(ListPointer headPointer) {
    ListPointer listPointer = headPointer->listNext;
    while (listPointer != NULL) {
        headPointer->listNext = listPointer->listNext;
        free(listPointer->listData);
        free(listPointer);
        listPointer = headPointer;
    }
}